﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace Common
{
    public class DelaySecondCall
    {
        public static uint OperationId = 0;

        // 操作ID
        public readonly uint id = ++OperationId;

        // 执行时间
        public readonly double executeTime;

        // 执行方法
        public readonly Action action;

        private DelaySecondCall(Action action, double delay)
        {
            this.action = action;
            executeTime = Timer.CurrentTime + delay;
        }

        public int CompareTo(DelaySecondCall other)
        {
            return executeTime.CompareTo(other.executeTime);
        }

        private static readonly SortedSet<DelaySecondCall> Operations = new SortedSet<DelaySecondCall>();

        public static void Update()
        {
            double currentTime = Timer.CurrentTime;
            while (Operations.Count > 0 && Operations.Min.executeTime <= currentTime)
            {
                var operation = Operations.Min;
                try
                {
                    operation.action?.Invoke();
                }
                catch (Exception e)
                {
#if UNITY_EDITOR
                Debug.LogError("DelaySecondCall Update Exception: " + e);    
#endif
                }
            }
        }
    }

    public class DelayFrameCall
    {
        public static uint OperationId = 0;

        // 操作ID
        public readonly uint id = ++OperationId;

        // 执行时间
        public readonly int executeFrame;

        // 执行方法
        public readonly Action action;

        private DelayFrameCall(Action action, int delayFrame)
        {
            this.action = action;
            executeFrame = Time.frameCount + delayFrame;
        }

        public int CompareTo(DelayFrameCall other)
        {
            return executeFrame.CompareTo(other.executeFrame);
        }

        private static readonly SortedSet<DelayFrameCall> Operations = new SortedSet<DelayFrameCall>();

        public static void Update()
        {
            int currentFrame = Time.frameCount;
            while (Operations.Count > 0 && Operations.Min.executeFrame <= currentFrame)
            {
                var operation = Operations.Min;
                try
                {
                    operation.action?.Invoke();
                }
                catch (Exception e)
                {
#if UNITY_EDITOR
                    Debug.LogError("DelayFrameCall Update Exception: " + e);
#endif
                }
            }
        }
    }

}